#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define N 32
#define M 128
#define R 0x1 //注册
#define L 0x2 //登录
#define Q 0x3  //查询单词
#define H 0x4  //历史记录
#define E 0x5 //退出

typedef struct{
	int type;//消息类型
	char name[N];//用户名
	char text[M];//单词  或 密码
}MSG;
#define LEN_SMG sizeof(MSG)
#define err_log(log)\
	do{\
	 perror(log);\
	 exit(1);\
	}while(0)

typedef struct sockaddr SA;
void do_register(int sockfd,MSG *msg);
int do_login(int sockfd,MSG *msg);
void do_query(int sockfd,MSG *msg);
void do_history(int sockfd,MSG *msg);
int main(int argc, const char *argv[])
{
	
	int sockfd;
	struct sockaddr_in serveraddr;
	socklen_t len=sizeof(SA);
	int cmd;
	char clean[M]={0};
	MSG msg;
	if(argc!=3)
	{
		printf("User:%s <IP> <port>\n",argv[0]);
		return -1;
	}

	if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)
	{
		err_log("fail to socket");
	}
	serveraddr.sin_family=AF_INET;
	serveraddr.sin_port=htons(atoi(argv[2]));
	serveraddr.sin_addr.s_addr=inet_addr(argv[1]);

	if(connect(sockfd,(SA*)&serveraddr,len)<0)// 客户端执行马上连接单词服务器
	{
		err_log("fail to connect");
	}

BEF:
	while(1)//一级的界面
	{
		 puts("**********************************************");
		 puts("1.Register            2.Login           3.Quit");
		 puts("**********************************************");
		 puts("input cmd>>>");
		 if(scanf("%d",&cmd)!=1)// 检测输入的格式对否
		 {
				puts("input error");
				fgets(clean,M,stdin);
				continue;
		 }
		 switch(cmd)//根据不同的输入命令执行不同的行为
		 {
			case 1:
				do_register(sockfd,&msg); 
				break;
			case 2:
				if(do_login(sockfd,&msg)==1)
				{
					goto NEXT;
				}
				else
				{
					break;
				}
			case 3:
				goto EXIT;
			default:
				puts("input error");
				break;

		 }
	}

EXIT:  
	
	msg.type=E;
	send(sockfd,&msg,LEN_SMG,0);
	close(sockfd);  //客户端退出的处理   
	exit(0);

NEXT:
	while(1)//二级界面
	{
		puts("**********************************************");
		puts("1.Query            2.History            3.Quit");
		puts("**********************************************");
		puts("input cmd>>>");
		if(scanf("%d",&cmd)!=1)
		 {
				puts("input error");
				fgets(clean,M,stdin);
				continue;
		 }
		 switch(cmd)
		 {
		    case 1:
                 do_query(sockfd,&msg);
				 break;
			case 2:
				 do_history(sockfd,&msg);
				 break;
			case 3:
				goto BEF;
				break;
			default:
				puts("cmd error");
				break;
		 }

	}

	return 0;
}
void do_register(int sockfd,MSG *msg)
{
	msg->type=R;
	puts("input name>>>");
	scanf("%s",msg->name);
	puts("input pwd>>>");
	scanf("%s",msg->text);

	send(sockfd,msg,LEN_SMG,0);//用户名密码发给服务器
	recv(sockfd,msg,LEN_SMG,0); //等待服务器回应
	if(strncmp(msg->text,"OK",2)==0)
	{
		puts("Register ok!");
		return;
	}
	else
	{
		puts("Register fail!");
		return;
		
	}
}
int do_login(int sockfd,MSG *msg)
{
	msg->type=L;
	puts("input name>>>");
	scanf("%s",msg->name);
	puts("input pwd>>>");
	scanf("%s",msg->text);

	send(sockfd,msg,LEN_SMG,0);//用户名密码发给服务器
	recv(sockfd,msg,LEN_SMG,0);//等待服务器回应
	if(strncmp(msg->text,"OK",2)==0)
	{
		 puts("Login ok!");
		 return 1;
	}
	else
	{
		puts("Login fail!");
		return -1;
	}
}
void do_query(int sockfd,MSG *msg)
{
	msg->type=Q;
	while(1)
	{
		puts("input word>>>");
		scanf("%s",msg->text);
		if(strncmp(msg->text,"##",2)==0)
		{
			break;
		}
		send(sockfd,msg,LEN_SMG,0);
		recv(sockfd,msg,LEN_SMG,0);
		if(strncmp(msg->text,"OK",2)==0)//服务器查到了
		{
			 	recv(sockfd,msg,LEN_SMG,0);//等待服务器发送单词的翻译
				if(strncmp(msg->text,"no found",8)==0)
				{
					puts("no found word!");
					puts("Query fail!");
					return;
				}
				else
				{
					printf("%s\n",msg->text);  //打印服务器发来的单词翻译
					puts("-----------------------------");
					puts("Query ok!");
					return;
				}

		}
		else
		{
				
					puts("Query fail!");
					return;
		}

			
	}

}
void do_history(int sockfd,MSG *msg)
{
	msg->type=H;
	int i=0;
	send(sockfd,msg,LEN_SMG,0);
	recv(sockfd,msg,LEN_SMG,0);
	if(strncmp(msg->text,"OK",2)==0)
	{
			
		while(1)
		{
			recv(sockfd,msg,LEN_SMG,0);//等待服务器发送的历史记录条目
			i++;
			if(strncmp(msg->text,"over",4)==0)//记录结束跳出循环
			{
				break;
			}

			printf("%-15s",msg->text);
			if(i%3==0)//每三个换行
				putchar(10);
		}
		puts("------------------------------------");
		puts("History ok!");
		return;
	}
	else
	{
		puts("History fail!");	
		return;
	}
}
